package net.easyjava.tools.lang;



import net.easyjava.tools.BaseTools;
import net.easyjava.tools.date.DateConstants;
import net.easyjava.tools.date.DateTools;

import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by wxnacy on 2015/11/30.
 */
public class StringTools extends BaseTools {
    private static final long serialVersionUID = 3052389541789255752L;
    private static final DecimalFormat decimalFormat;
    private final static char[] digits = {
            '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b',
            'c', 'd', 'e', 'f', 'g', 'h',
            'i', 'j', 'k', 'l', 'm', 'n',
            'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z'
    };

    static {
        NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ENGLISH);
        decimalFormat = (DecimalFormat) numberFormat;
        decimalFormat.applyPattern("#.##");
    }
    /**
     * 以十六进制（基数 16）无符号整数形式返回一个整数参数的字符串表示形式，并转换为大写
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src){
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0){
            return null;
        }
        String hv;
        for (int i = 0; i < src.length; i++){
            // 以十六进制（基数 16）无符号整数形式返回一个整数参数的字符串表示形式，并转换为大写
            hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
            if (hv.length() < 2){
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }

    /**
     * 获取带有位数参数的随机数
     * @param len 随机数的位数
     * @return
     */
    public static String getRandom(int len) {
        char[] randomArray = new char[len];
        Random r = new Random();
        for (int i = 0; i < len; i++) {
            randomArray[i] = digits[Math.abs(r.nextInt(digits.length))];
        }
        return new String(randomArray);
    }

    /**
     * 获取 yyyy/MM/dd/ 格式后缀为随机数的目录
     * @param len
     * @return
     */
    public static String getRandomDir(int len){
        return String.format("%s%s/", DateTools.format(System.currentTimeMillis(), DateConstants.DATE_FILE_PATH), getRandom(len).toUpperCase());
    }

    public static synchronized String limitDecimalTo2(double d) {
        return decimalFormat.format(d);
    }

    /**
     * 将byte长度格式为可读大小
     * @param len
     * @return
     */
    public static String byteSizeFormat(long len) {
        double val = 0.0;
        String ending = "";
        if (len < 1024 * 1024) {
            val = (1.0 * len) / 1024;
            ending = " KB";
        } else if (len < 1024 * 1024 * 1024) {
            val = (1.0 * len) / (1024 * 1024);
            ending = " MB";
        } else if (len < 1024L * 1024 * 1024 * 1024) {
            val = (1.0 * len) / (1024 * 1024 * 1024);
            ending = " GB";
        } else if (len < 1024L * 1024 * 1024 * 1024 * 1024) {
            val = (1.0 * len) / (1024L * 1024 * 1024 * 1024);
            ending = " TB";
        } else {
            val = (1.0 * len) / (1024L * 1024 * 1024 * 1024 * 1024);
            ending = " PB";
        }
        return limitDecimalTo2(val) + ending;
    }

    /**
     * 判断字符串是否为空值
     * @param str
     * @return
     */
    public static boolean isNull(String str) {
        if (str == null || "".equalsIgnoreCase(str)) {
            return true;
        }
        return false;
    }

    /**
     * 判断字符串是否为空，去掉空格
     * @param str
     * @return
     */
    public static boolean isEmpty(String str) {
        return str == null || str.trim().length() == 0;
    }


    /**
     * 判断字符串是否为邮箱
     * @param email
     * @return
     */
    public static boolean isEmail(String email){
        Pattern p = Pattern.compile("^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
        Matcher m = p.matcher(email);
        return m.matches();
    }

    /**
     * 判断字符串是否为手机号
     * @param mobile
     * @return
     */
    public static boolean isMobile(String mobile){
        Pattern p = Pattern.compile("^1[3-9]\\d{9}$");
//		Pattern p = Pattern.compile("^[1]([3][0-9]{1}|59|58|88|89)[0-9]{8}$");
//		Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
        Matcher m = p.matcher(mobile);
        return m.matches();

    }

    /**
     * 获取短连接
     * @param url
     * @return
     */
    public static String getShortUrl(String url) {
        // 可以自定义生成 MD5 加密字符传前的混合 KEY
        String key = "test";
        // 要使用生成 URL 的字符
        String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h",
                "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
                "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
                "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
                "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
                "U", "V", "W", "X", "Y", "Z"

        };
        // 对传入网址进行 MD5 加密
        String hex = md5ByHex(key + url);

        String[] resUrl = new String[4];
        for (int i = 0; i < 4; i++) {

            // 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算
            String sTempSubString = hex.substring(i * 8, i * 8 + 8);

            // 这里需要使用 long 型来转换，因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用long ，则会越界
            long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);
            String outChars = "";
            for (int j = 0; j < 6; j++) {
                // 把得到的值与 0x0000003D 进行位与运算，取得字符数组 chars 索引
                long index = 0x0000003D & lHexLong;
                // 把取得的字符相加
                outChars += chars[(int) index];
                // 每次循环按位右移 5 位
                lHexLong = lHexLong >> 5;
            }
            // 把字符串存入对应索引的输出数组
            resUrl[i] = outChars;
        }

//        for (int i = 0; i < resUrl.length; i++) {
//            System.out.println("[" + i + "]:" + resUrl[i]);
//        }
        Random random=new Random();
        int j=random.nextInt(4);//产成4以内随机数
//        System.out.println("短链接:"+resUrl[j]);//随机取一个作为短链
        return resUrl[j];
    }
    /**
     * MD5加密(32位大写)
     * @param src
     * @return
     */
    protected static String md5ByHex(String src) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = src.getBytes();
            md.reset();
            md.update(b);
            byte[] hash = md.digest();
            String hs = "";
            String stmp = "";
            for (int i = 0; i < hash.length; i++) {
                stmp = Integer.toHexString(hash[i] & 0xFF);
                if (stmp.length() == 1)
                    hs = hs + "0" + stmp;
                else {
                    hs = hs + stmp;
                }
            }
            return hs.toUpperCase();
        } catch (Exception e) {
            return "";
        }
    }


    /**
     * 对字符串escape
     * name:escape
     * des:
     * author:wxnacy
     * date:2015-4-2下午6:34:48
     * @param src
     * @return
     */
    public static String escape(String src) {
        int i;
        char j;
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length() * 6);
        for (i = 0; i < src.length(); i++) {
            j = src.charAt(i);
            if (Character.isDigit(j) || Character.isLowerCase(j)
                    || Character.isUpperCase(j))
                tmp.append(j);
            else if (j < 256) {
                tmp.append("%");
                if (j < 16)
                    tmp.append("0");
                tmp.append(Integer.toString(j, 16));
            } else {
                tmp.append("%u");
                tmp.append(Integer.toString(j, 16));
            }
        }
        return tmp.toString();
    }

    /**
     * 对字符窜进行unescape
     * name:unescape
     * des:
     * author:wxnacy
     * date:2015-4-2下午6:37:33
     * @param src
     * @return
     */
    public static String unescape(String src) {
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length());
        int lastPos = 0, pos = 0;
        char ch;
        while (lastPos < src.length()) {
            pos = src.indexOf("%", lastPos);
            if (pos == lastPos) {
                if (src.charAt(pos + 1) == 'u') {
                    ch = (char) Integer.parseInt(src
                            .substring(pos + 2, pos + 6), 16);
                    tmp.append(ch);
                    lastPos = pos + 6;
                } else {
                    ch = (char) Integer.parseInt(src
                            .substring(pos + 1, pos + 3), 16);
                    tmp.append(ch);
                    lastPos = pos + 3;
                }
            } else {
                if (pos == -1) {
                    tmp.append(src.substring(lastPos));
                    lastPos = src.length();
                } else {
                    tmp.append(src.substring(lastPos, pos));
                    lastPos = pos;
                }
            }
        }
        return tmp.toString();
    }


    /**
     * 将html中特殊符号进行转义
     * @param content
     * @return
     */
    public static String transHtml(String content){
        content = content.replaceAll("&", "&amp;");
        content = content.replaceAll("<", "&lt;");
        content = content.replaceAll(">", "&gt;");
        content = content.replaceAll("\r", "&lt;br&gt;");
        content = content.replaceAll("\t", "&nbsp;&nbsp;");
        content = content.replaceAll("\"", "&quot");
        content = content.replaceAll("'", "&apos;");
        content = content.replaceAll(" ", "&nbsp;");
        return content;
    }
    public static void main(String[] args) {
        String content = "&&&&&   <div></div><p></p>\t\"\t\"\t\"'''";
        System.out.println("transHtml(content) = " + transHtml(content));
    }

}

